package demoMod.anm2editor.enums;

import com.badlogic.gdx.math.Interpolation;
import demoMod.anm2editor.model.Anchor;

import java.util.ArrayList;
import java.util.List;

/**
 * 曲线类型，目前仅支持折线和贝塞尔曲线
 */
public enum CustomCurveType {
    /**
     * 折线
     */
    BROKEN_LINE {
        @Override
        public float apply(List<Anchor> anchors, float a) {
            for (Anchor anchor : anchors) {
                if (anchors.indexOf(anchor) != anchors.size() - 1) {
                    Anchor nextAnchor = anchors.get(anchors.indexOf(anchor) + 1);
                    if (anchor.getX() < a && nextAnchor.getX() >= a) {
                        return Interpolation.linear.apply(anchor.getY(), nextAnchor.getY(), (a - anchor.getX()) / (nextAnchor.getX() - anchor.getX()));
                    }
                }
            }
            return a <= 0 ? anchors.get(0).getY() : anchors.get(anchors.size() - 1).getY();
        }
    },
    /**
     * 贝塞尔曲线
     */
    BEZIER_CURVE {
        @Override
        public float apply(List<Anchor> anchors, float a) {
            if (anchors.size() > 2) {
                List<Anchor> subAnchors = new ArrayList<>();
                for (Anchor anchor : anchors) {
                    if (anchors.indexOf(anchor) != anchors.size() - 1) {
                        Anchor nextAnchor = anchors.get(anchors.indexOf(anchor) + 1);
                        Anchor newAnchor = new Anchor();
                        newAnchor.setX((nextAnchor.getX() - anchor.getX()) * a + anchor.getX());
                        newAnchor.setY((nextAnchor.getY() - anchor.getY()) * a + anchor.getY());
                        subAnchors.add(newAnchor);
                    }
                }
                return apply(subAnchors, a);
            }
            return Interpolation.linear.apply(anchors.get(0).getY(), anchors.get(1).getY(), a);
        }
    },
    /**
     * 钢笔
     */
    PEN {
        @Override
        public float apply(List<Anchor> anchors, float a) {
            for (Anchor anchor : anchors) {
                if (anchors.indexOf(anchor) != anchors.size() - 1) {
                    Anchor nextAnchor = anchors.get(anchors.indexOf(anchor) + 1);
                    if (anchor.getX() < a && nextAnchor.getX() >= a) {
                        List<Anchor> subAnchors = new ArrayList<>();
                        subAnchors.add(anchor);
                        subAnchors.add(anchor.getBezierPoints().get(anchor.getBezierPoints().size() - 1));
                        subAnchors.add(nextAnchor.getBezierPoints().get(0));
                        subAnchors.add(nextAnchor);
                        return BEZIER_CURVE.apply(subAnchors, (a - anchor.getX()) / (nextAnchor.getX() - anchor.getX()));
                    }
                }
            }
            return BEZIER_CURVE.apply(anchors, a);
        }
    }
    ;
    public abstract float apply(List<Anchor> anchors, float a);
}
